﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;

namespace 自动校园网登陆
{
    public partial class Login_Form : Form
    {
        [DllImport("user32", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern IntPtr GetFocus();
        [DllImport("user32", EntryPoint = "SetForegroundWindow")]
        public static extern bool SetFocus(IntPtr hWnd);
        [DllImport("wininet.dll")]
        private extern static bool InternetGetConnectedState(int Description, int ReservedValue);

        Dictionary<string, string> errors = new Dictionary<string, string>
            {
                { "E2531", "用户不存在" },
                { "E2532", "您的两次认证的间隔太短,请稍候10秒后再重试登录" },
                { "E2533", "密码错误次数超过限制，请5分钟后再重试登录" },
                { "E2534", "有代理行为被暂时禁用" },
                { "E2535", "认证系统已经被禁用" },
                { "E2536", "授权已过期" },
                { "E2553", "帐号或密码错误" },
                { "E2601", "您使用的不是专用客户端,IPOE-PPPoE混杂模式请联系管理员重新打包客户端程序" },
                { "E2602", "您还没有绑定手机号或绑定的非联通手机号码" },
                { "E2606", "用户被禁用" },
                { "E2607", "接口被禁用" },
                { "E2611", "您当前使用的设备非该账号绑定设备 请绑定或使用绑定的设备登入" },
                { "E2613", "NAS PORT绑定错误" },
                { "E2614", "MAC地址绑定错误" },
                { "E2615", "IP地址绑定错误" },
                { "E2616", "用户已欠费" },
                { "E2620", "已经在线了" },
                { "E2621", "已经达到授权人数" },
                { "E2806", "找不到符合条件的产品" },
                { "E2807", "找不到符合条件的计费策略" },
                { "E2808", "找不到符合条件的控制策略" },
                { "E2833", "IP不在DHCP表中，需要重新拿地址。" },
                { "E2840", "校内地址不允许访问外网" },
                { "E2841", "IP地址绑定错误" },
                { "E2842", "IP地址无需认证可直接上网" },
                { "E2843", "IP地址不在IP表中" },
                { "E2844", "IP地址在黑名单中" }
            };
        private string[] domains = { "@cucc", "@cmcc", "@jxnu", "@ctcc" };
        private bool isRunning = true, isColdDown = false;
        private IntPtr han;
        private bool isDragging;
        private Point mouseLocation;

        public Login_Form()
        {
            System.AppDomain.CurrentDomain.AssemblyResolve += new System.ResolveEventHandler(CurrentDomain_AssemblyResolve);
            InitializeComponent();
        }

        /// <summary>
        /// 用来调用嵌入到exe的DLL资源
        /// </summary>
        private System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, System.ResolveEventArgs args)
        {
            System.Console.WriteLine(args.Name);
            string dllName = args.Name.Contains(",") ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll", "");
            dllName = dllName.Replace(".", "_");
            if (dllName.EndsWith("_resources")) return null;
            System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());
            byte[] bytes = (byte[])rm.GetObject(dllName);
            return System.Reflection.Assembly.Load(bytes);
        }


        /// <summary>
        /// 判断是否运行在管理员模式下
        /// </summary>
        public static bool IsRunAsAdmin()
        {
            WindowsIdentity id = WindowsIdentity.GetCurrent();
            WindowsPrincipal principal = new WindowsPrincipal(id);
            return principal.IsInRole(WindowsBuiltInRole.Administrator);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            han = this.Handle;

            string path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            string filePath = path + "\\jxnu.ini";
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            if (!File.Exists(filePath))
                File.Create(filePath).Dispose();
            UserData.username = Util.Read("JXNU", "username", "", filePath);
            UserData.password = Util.Read("JXNU", "password", "", filePath);
            UserData.domain = Util.Read("JXNU", "network", "0", filePath); // 读取配置文件

            textBox1.Text = UserData.username;
            textBox2.Text = UserData.password;
            comboBox1.SelectedIndex = int.Parse(UserData.domain);

            if (!IsRunAsAdmin())
                checkBox2.Enabled = false;


            string pathh = GetType().Assembly.Location;
            RegistryKey rk = Registry.CurrentUser;
            RegistryKey rk2 = rk.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run");
            if(rk2.GetValue("JXNUNet") == null || rk2.GetValue("JXNUNet").ToString() != pathh)
                checkBox2.Checked = false;
            else 
                checkBox2.Checked = true;

            if (UserData.username.Equals("") || UserData.password.Equals(""))
            {
                MessageBox.Show("首次使用请设置校园网账号密码");
                //this.WindowState = FormWindowState.Normal;
                panel2.Visible = false;
                panel2.Enabled = false;
                panel3.Visible = true;
                panel3.Enabled = true;
                Point p1 = panel2.Location;
                Point p2 = panel3.Location;
                panel3.Location = p1;
                panel2.Location = p2;

                UserData.username = Util.Read("JXNU", "username", "", filePath);
                UserData.password = Util.Read("JXNU", "password", "", filePath);
                UserData.domain = Util.Read("JXNU", "network", "", filePath);
            }else
            {
                timer1.Enabled = true;
                this.WindowState = FormWindowState.Minimized;
            }
        }

        /// <summary>
        /// timer1 Tick事件，2秒尝试一次登录操作
        /// </summary>
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (!isColdDown && isRunning)
            {
                if (Util.IsJxnuWLAN())
                {
                    string network_code = Util.GetNetworkStatusCode();
                    if (network_code == "not_online_error")
                    {
                        LoginHandler login = new LoginHandler(UserData.username + domains[int.Parse(UserData.domain)], UserData.password);
                        string login_error_msg = login.TryLogin();
                        if (login_error_msg == "offline_error")
                            return;
                        Console.WriteLine(login_error_msg);

                        Regex r = new Regex("\"ecode\":\"(.*?)\",\"error\":\"(.*?)\"|\"ecode\":([^\"]*?),\"error\":\"(.*?)\"");
                        string ecode = "", error = "";
                        GroupCollection group = r.Match(login_error_msg).Groups;
                        for (int i = 1; i < group.Count; ++i)
                        {
                            if (group[i].Success)
                            {
                                ecode = group[i].Value;
                                error = group[i + 1].Value;
                                break;
                            }
                        }

                        if (ecode == "0")
                        {
                            if (error == "ok")
                            {
                                notifyIcon1.BalloonTipText = "JXNU校园网自动登陆";
                                notifyIcon1.BalloonTipTitle = "登录成功！";
                                notifyIcon1.ShowBalloonTip(0);
                            }
                            else if (error == "ip_already_online_error")
                            {

                            }
                            else if (error == "speed_limit_error")
                            {
                                // 间隔过短
                                notifyIcon1.BalloonTipText = "JXNU校园网自动登陆";
                                notifyIcon1.BalloonTipTitle = "认证请求太频繁，冷却5分钟";
                                notifyIcon1.ShowBalloonTip(0);

                                isColdDown = true;

                                new Thread(() =>
                                {
                                    Thread.Sleep(1000 * 60 * 5);
                                    isColdDown = false;
                                }).Start();
                            }
                        }
                        else if (ecode == "E2532")
                        {
                            // 间隔过短
                            notifyIcon1.BalloonTipText = "JXNU校园网自动登陆";
                            notifyIcon1.BalloonTipTitle = "认证请求太频繁，冷却5分钟";
                            notifyIcon1.ShowBalloonTip(0);

                            isColdDown = true;

                            new Thread(() =>
                            {
                                Thread.Sleep(1000 * 60 * 5);
                                isColdDown = false;
                            }).Start();
                        }
                        else if (errors.ContainsKey(ecode))
                        {
                            notifyIcon1.BalloonTipText = "JXNU校园网自动登陆";
                            notifyIcon1.BalloonTipTitle = $"{errors[ecode]},已停止自动登录";
                            notifyIcon1.ShowBalloonTip(0);

                            checkBox1.Checked = false;
                            isRunning = false;
                        }
                        else
                        {
                            notifyIcon1.BalloonTipText = "JXNU校园网自动登陆";
                            notifyIcon1.BalloonTipTitle = $"未知错误，已停止自动登录，错误码：{ecode}-{error}";
                            notifyIcon1.ShowBalloonTip(0);

                            checkBox1.Checked = false;
                            isRunning = false;
                        }
                    }
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            panel2.Visible = false;
            panel2.Enabled = false;
            panel3.Visible = true;
            panel3.Enabled = true;
            Point p1 = panel2.Location;
            Point p2 = panel3.Location;
            panel3.Location = p1;
            panel2.Location = p2;
        }

        private void Login_Form_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.ShowInTaskbar = false; // 在任务栏中显示该窗口
                this.Visible = false;
            }
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.Visible = true;
            this.WindowState = FormWindowState.Normal;
            this.ShowInTaskbar = true;
            if (han != GetFocus())
                SetFocus(han);
        }

        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            if (!isColdDown && isRunning)
            {
                if (Util.IsJxnuWLAN())
                {
                    string network_code = Util.GetNetworkStatusCode();
                    if (network_code == "not_online_error")
                    {
                        LoginHandler login = new LoginHandler(UserData.username + domains[int.Parse(UserData.domain)], UserData.password);
                        string login_error_msg = login.TryLogin();
                        Console.WriteLine(login_error_msg);

                        Regex r = new Regex("\"ecode\":\"(.*?)\",\"error\":\"(.*?)\"|\"ecode\":([^\"]*?),\"error\":\"(.*?)\"");
                        string ecode = "", error = "";
                        GroupCollection group = r.Match(login_error_msg).Groups;
                        for (int i = 1; i < group.Count; ++i)
                        {
                            if (group[i].Success)
                            {
                                ecode = group[i].Value;
                                error = group[i + 1].Value;
                                break;
                            }
                        }

                        if (ecode == "0")
                        {
                            if (error == "ok")
                            {
                                notifyIcon1.BalloonTipText = "JXNU校园网自动登陆";
                                notifyIcon1.BalloonTipTitle = "登录成功！";
                                notifyIcon1.ShowBalloonTip(0);
                            }
                            else if (error == "ip_already_online_error")
                            {

                            }
                            else if (error == "speed_limit_error")
                            {
                                // 间隔过短
                                notifyIcon1.BalloonTipText = "JXNU校园网自动登陆";
                                notifyIcon1.BalloonTipTitle = "认证请求太频繁，冷却5分钟";
                                notifyIcon1.ShowBalloonTip(0);

                                isColdDown = true;

                                new Thread(() =>
                                {
                                    Thread.Sleep(1000 * 60 * 5);
                                    isColdDown = false;
                                }).Start();
                            }
                            else if (ecode == "E2532")
                            {
                                // 间隔过短
                                notifyIcon1.BalloonTipText = "JXNU校园网自动登陆";
                                notifyIcon1.BalloonTipTitle = "认证请求太频繁，冷却5分钟";
                                notifyIcon1.ShowBalloonTip(0);

                                isColdDown = true;

                                new Thread(() =>
                                {
                                    Thread.Sleep(1000 * 60 * 5);
                                    isColdDown = false;
                                }).Start();
                            }
                            else if (errors.ContainsKey(ecode))
                            {
                                notifyIcon1.BalloonTipText = "JXNU校园网自动登陆";
                                notifyIcon1.BalloonTipTitle = $"{errors[ecode]},已停止自动登录";
                                notifyIcon1.ShowBalloonTip(0);

                                checkBox1.Checked = false;
                                isRunning = false;
                            }
                            else
                            {
                                notifyIcon1.BalloonTipText = "JXNU校园网自动登陆";
                                notifyIcon1.BalloonTipTitle = $"未知错误，已停止自动登录，错误码：{ecode}-{error}";
                                notifyIcon1.ShowBalloonTip(0);

                                checkBox1.Checked = false;
                                isRunning = false;
                            }
                        }
                    }
                }
            }
        }

        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Environment.Exit(0);
        }

        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                mouseLocation = new Point(-e.X, -e.Y);
                isDragging = true;
            }
        }

        private void panel1_MouseUp(object sender, MouseEventArgs e)
        {
            if (isDragging)
            {
                isDragging = false;//鼠标已抬起，标识为false
            }
        }

        private void panel1_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDragging)
            {
                Point newMouseLocation = MousePosition;
                //获取鼠标当前位置
                newMouseLocation.Offset(mouseLocation.X, mouseLocation.Y);
                //用鼠标当前位置加上鼠标相较于窗体左上角的
                //坐标的负数，也就获取到了新的窗体左上角位置
                Location = newMouseLocation;//设置新的窗体左上角位置
            }
        }

        private void myButton1_Click(object sender, EventArgs e)
        {
            Environment.Exit(0);
        }

        private void myButton2_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if(checkBox1.Checked)
            {
                isRunning = true;
            }
            else
            {
                isRunning = false;
            }
        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            string path = GetType().Assembly.Location;
            RegistryKey rk = Registry.CurrentUser;
            RegistryKey rk2 = rk.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run");
            if (checkBox2.Checked)
            {
                rk2.SetValue("JXNUNet", path);
                rk2.Close();
                rk.Close();
            }
            else
            {
                if(rk2.GetValue("JXNUNet") != null)
                {
                    rk2.DeleteValue("JXNUNet");
                    rk2.Close();
                    rk.Close();
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (textBox1.Text == "")
            {
                MessageBox.Show("请输入学号！");
                return;
            }
            else if (textBox2.Text == "")
            {
                MessageBox.Show("请输入密码！");
                return;
            }
            else if (comboBox1.Text == "")
            {
                MessageBox.Show("请选择运营商！");
                return;
            }

            string path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            string filePath = path + "\\jxnu.ini";
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            if (!File.Exists(filePath))
                File.Create(filePath).Dispose();

            Util.Write("JXNU", "username", textBox1.Text, filePath);
            Util.Write("JXNU", "password", textBox2.Text, filePath);
            Util.Write("JXNU", "network", comboBox1.SelectedIndex.ToString(), filePath);

            UserData.username = textBox1.Text;
            UserData.password = textBox2.Text;
            UserData.domain = comboBox1.SelectedIndex.ToString();

            panel3.Visible = false;
            panel3.Enabled = false;
            panel2.Enabled = true;
            panel2.Visible = true;

            Point p1 = panel2.Location;
            Point p2 = panel3.Location;
            panel3.Location = p1;
            panel2.Location = p2;

            timer1.Enabled = true;
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            SolidBrush drawBrush = new SolidBrush(Color.SteelBlue);
            e.Graphics.DrawString("校园网自动登录", new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134), drawBrush, new PointF(5, 5));
        }
    }
}
